package de.koller.aframe.util.noise.n1D;

import de.koller.aframe.util.math.FunctionPreview;
import de.koller.aframe.util.math.IFunction;
import de.koller.aframe.util.math.interpolation.CubicInterpolation;
import java.util.Random;

public class Noise1D implements IFunction {

	public final float[] noise;

	public Noise1D( Random rnd, int size ) {
		if( size < 4 )
			throw new IllegalArgumentException( "must have at least size 4" );
		this.noise = new float[size];
		
		for( int x = 0; x < noise.length; x++ )
			noise[x] = rnd.nextFloat();
	}

	public Noise1D( float[] noise ) {
		this.noise = noise;
	}
	
	@Override
	public float getValue( float x ) {
		if( x >= 1 || x < 0 )
			return 0;
		
		int a = noise.length - 3;
		x *= a;
		
		float zx = x % 1f;
		
		int dx = (int)Math.floor( x );
		
		return CubicInterpolation.cubic( zx, noise[0+dx], noise[1+dx], noise[2+dx], noise[3+dx] );
	}
	
	/** sets the maximum value to 1 and the minumum value to 0. */
	public void normalize() {
		float maxV = Float.MIN_VALUE;
		float minV = Float.MAX_VALUE;
		
		for( int x = 0; x < noise.length; x++ ) {
			maxV = Math.max( noise[x], maxV );
			minV = Math.min( noise[x], minV );
		}
		
		for( int x = 0; x < noise.length; x++ )
			noise[x] = (noise[x] - minV) * (1f / (maxV-minV));
	}
	
	public static void main( String[] args ) {
		Random r = new Random();
		FunctionPreview.dontscale( -.25f );
		while( true ) {
			Noise1D n = new Noise1D( new float[] { 0, 1, 0, 1 } );
			//n.normalize();
			FunctionPreview.showFunction( -1, 2, n );
		}
	}
	
}
